#ifndef BOARD_Tue_Aug_11_20_36_27_2015_H
#define BOARD_Tue_Aug_11_20_36_27_2015_H

#include <ostream>

struct Chess
{
    Chess()
    {
        value = 0;
        newValue = '0';
        for(auto& var: neighbor)
        {
            var = 0;
        }
    }

    void init(Chess* board, int i, char value) 
    {
        this->value = value;
        if(i-5 >= 0) neighbor[0] = &board[i-5];
        if(i-4 >= 0 ) neighbor[1] = &board[i-4];
        if(i-3 >= 0) neighbor[2] = &board[i-3];
        if(i-1 >= 0) neighbor[3] = &board[i-1];
        if(i+1 <= 15) neighbor[4] = &board[i+1];
        if(i+3 <= 15) neighbor[5] = &board[i+3];
        if(i+4 <= 15) neighbor[6] = &board[i+4];
        if(i+5 <= 15) neighbor[7] = &board[i+5];
        if(i%4 == 0) neighbor[0]=neighbor[3]=neighbor[5]=0;
        if((i+1)%4 == 0) neighbor[2]=neighbor[4]=neighbor[7]=0;
    }

    void evolve()
    {
        for(int i = 0; i< 8;i++)
        {
            if(neighbor[i] == 0 || value != 'w') continue;
            neighbor[i]->change(*this, i, true);
        }
    }
    void dump(bool old)
    {
        std::cout<<(old?value:newValue);
    }
private:
    void change(Chess& chess,int i,bool init)
    {
        if(chess.value == value)
        {
            return;
        }
        if(value == '0'&& !init) {
            newValue = 'w';   
            return;
        }
        if(neighbor[i]!=0)
        {
            return neighbor[i]->change(chess, i, false);
        }
    }
    
private:
    Chess* neighbor[8];
    char value;
    char newValue;
};

struct Board
{
    template<int L>
    void init(const char (&list)[L])
    {
        for(int i= 0; i< L;++i)
        {
            chesses[i].init(chesses, i, list[i]);
        }
        dump(true);
    }

    void evolve(std::ostream& os)
    {
        for(auto& var: chesses)
        {
            var.evolve();
        }
        dump(false);
    }

    void dump(bool old)
    {
        int i = 0;
        for(auto& var: chesses)
        {
            var.dump(old);
            if((++i)%4 == 0) std::cout<<std::endl;
        }
        std::cout<<std::endl;
    }
private:
    Chess chesses[16]; 
};

#endif
